#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

class Matrix
{
public:
	void SetValue(const int i, const int j, double value)
	{
		_m[_col*(i - 1) + j - 1] = value;
	}
	double GetValue(const int i, const int j) const
	{
		return _m[_col*(i - 1) + j - 1];
	}
	int GetRowCount()const
	{
		return _row;
	}
	int GetColCount() const
	{
		return _col;
	}
	Matrix()
		:_row(0), _col(0), _m(nullptr)
	{}
	Matrix(const int row,const int col)
		:_row(row), _col(col)
	{
		_m = new double[row*col];
		for (size_t i = 0; i < row * col; i++)
		{
			_m[i] = 0;
		}
	}
	Matrix(const Matrix& m)
		:_row(m.GetRowCount()), _col(m.GetColCount())
	{
		_m = new double[_row*_col];
		for (size_t i = 1; i <= _row; i++)
		{
			for (size_t j = 1; j <= _col; j++)
			{
				SetValue(i, j, m.GetValue(i, j));
			}
		}
	}
	~Matrix()
	{
		delete[] _m;
		_m = nullptr;
		_row = _col = 0;
	}
	Matrix Multiply(Matrix& m)
	{
		Matrix tmp(GetRowCount(), m.GetColCount());
		if (GetColCount() != m.GetRowCount())
		{
			cout << "Illegal Matrix Multiplication" << endl;
			return Matrix(0, 0);
		}
		else
		{
			for (size_t trow = 1; trow <= GetRowCount(); trow++)
			{
				for (size_t tcol = 1; tcol <= m.GetColCount(); tcol++)
				{
					double d = 0;
					for (size_t i = 1, j = 1; i <= GetColCount() && j <= m.GetRowCount(); i++, j++)
					{
						d += GetValue(trow, i) * m.GetValue(j, tcol);
					}
					tmp.SetValue(trow, tcol, d);
				}
			}
		}
		return tmp;
	}
	Matrix Transpose() const
	{
		Matrix tmp(GetColCount(), GetRowCount());
		for (int i = 1; i <= GetRowCount(); i++)
		{
			for (int j = 1; j <= GetColCount(); j++)
			{
				tmp.SetValue(j, i, GetValue(i, j));
			}
		}
		return tmp;
	}
	void Print()
	{
		for (int i = 1; i <= GetRowCount(); i++)
		{
			for (int j = 1; j <= GetColCount();j++)
			{
				cout << GetValue(i, j)<<" ";
			}
			cout << endl;
		}
		cout << endl;
	}
private:
	size_t _row;
	size_t _col;
	double* _m;
};

void test()
{
	Matrix m1(4, 3);
	Matrix m2(3, 2);
	m1.Print();
	m2.Print();
	double cnt = 1;
	for (size_t i = 1; i <= m1.GetRowCount(); i++)
	{
		for (size_t j = 1; j <= m1.GetColCount(); j++)
		{
			m1.SetValue(i, j, cnt);
			cnt++;
		}
	}
	cnt = 1;
	for (size_t i = 1; i <= m2.GetRowCount(); i++)
	{
		for (size_t j = 1; j <= m2.GetColCount(); j++)
		{
			m2.SetValue(i, j, cnt);
			cnt++;
		}
	}
	m1.Print();
	m2.Print();
	m1.Multiply(m2).Print();
	m1.Transpose().Print();
}
int main()
{
	test();
	return 0;
}